package network.messages;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

/**
 * Classe singleton. Instancie des messages sérialisés
 * 
 * @author Antoine Gassot
 */
public class MessageFactory {
    /**
     * Caractère séparant le header de la suite du message
     */
    protected static String HEADER_CHARACTER = ":";

    /**
     * Instance du singleton
     */
    private static MessageFactory instance;

    protected HashMap<String, Class> objects;

    /**
     * Le constructeur est privé, c'est un singleton !
     */
    private MessageFactory() {
        objects = new HashMap<String, Class>();
        objects.put("PING", PingMessage.class);
        objects.put("PONG", PongMessage.class);
    }

    /**
     * Retourne l'instance. Singleton.
     * 
     * @return L'instance du singleton
     */
    public static MessageFactory getInstance() {
        if (instance == null) {
            instance = new MessageFactory();
        }
        return instance;
    }

    /**
     * Instancie un AbstractMessage à partir de sa version sérialisée.
     * 
     * @param string La version sérialisée
     * @return Un AbstractMessage ou null en cas d'erreur
     */
    public AbstractMessage deserialize(String string) {
        int index = string.indexOf(HEADER_CHARACTER);
        if (index == -1) {
            return null;
        }

        String[] splitMessage = string.split(HEADER_CHARACTER);
        if (objects.containsKey(splitMessage[0])) {
            try {
                AbstractMessage instance = (AbstractMessage) objects
                        .get(splitMessage[0]).newInstance();
                if(splitMessage[1].compareTo("1") == 0) {
                	instance.setBroadcast(true);
                }
                instance.setContenu(splitMessage[2]);
                return instance;
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
        }

        return null;
    }

    public String serialize(AbstractMessage message) {
        Iterator<Entry<String, Class>> iterator = objects.entrySet().iterator();
        Entry<String, Class> item;
        while (iterator.hasNext()) {
            item = iterator.next();

            if (item.getValue() == message.getClass()) {
                return item.getKey() + HEADER_CHARACTER + (message.getBroadcast() ? '1' : '0') +
                	HEADER_CHARACTER + message.getContenu();
            }
        }

        return null;
    }
}
